package me.yuzho.study.concurrency;

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static net.mindview.util.Print.*;


class Sender implements Runnable {
    
    private Random rand = new Random(47);
    private PipedWriter out = new PipedWriter();
    
    public PipedWriter getPipedWriter() { return out; }

    @Override
    public void run() {
        
        try {
            
            while(true){
                for(char c = 'A'; c <= 'z'; c++ ) {
                    out.write(c);
                    TimeUnit.MILLISECONDS.sleep(rand.nextInt(500));
                }
            }
            
        } catch (IOException e) {
            print(e + " Sender write exception");
        } catch (InterruptedException e) {
            print(e + " Sender sleep interrupted");
        }
        
    }
}

class Receiver implements Runnable {
    private PipedReader in;
    
    public Receiver(Sender sender) throws IOException {
        in = new PipedReader(sender.getPipedWriter());
    }

    @Override
    public void run() {
        
        try {
            while (true) {
                printnb("Read: " + (char)in.read() + ", ");
            }
        } catch(IOException e) {
            print(e + " Receiver read exception");
        }
        
    }
}

public class PipedIO {

    public static void main(String[] args) throws IOException, InterruptedException {
        Sender sender = new Sender();
        
        Receiver receiver = new Receiver(sender);
        
        ExecutorService executorService = Executors.newCachedThreadPool();
        
        executorService.execute(sender);
        executorService.execute(receiver);
        
        TimeUnit.SECONDS.sleep(4);
        
        executorService.shutdownNow();
        
    }
}
